package com.raorao.config.listener;

import com.alibaba.fastjson.JSON;
import com.raorao.config.common.constants.ConfigChangeEnum;
import com.raorao.config.common.constants.ConfigConstant;
import com.raorao.config.event.ConfigChangeEvent;
import com.raorao.config.dao.pojo.ConfigInfo;
import com.raorao.config.dao.pojo.FileInfo;
import com.raorao.config.dao.pojo.ProjectInfo;
import com.raorao.config.dao.repository.ConfigInfoRepository;
import com.raorao.config.dao.repository.FileInfoRepository;
import com.raorao.config.dao.repository.ProjectInfoRepository;
import com.raorao.config.service.process.ConfigModel;
import com.raorao.config.service.register.ServiceRegister;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * rpc服务提供者清单变更监听
 * @author raorao
 * @since 1.0.0
 */
@Component
public class ConfigChangeListener implements ApplicationListener<ConfigChangeEvent> {

    private static Logger logger = LoggerFactory.getLogger(ConfigChangeListener.class);

    @Autowired
    private ProjectInfoRepository projectInfoRepository;
    @Autowired
    private FileInfoRepository fileInfoRepository;
    @Autowired
    private ConfigInfoRepository configInfoRepository;
    @Autowired
    private ServiceRegister serviceRegister;
    /**
     * @Async 注解代表该事件为异步处理，要想实现异步，还需要在启动类上增加 @EnableAsync注解
     * @param event
     */
    @Async
    @Override
    public void onApplicationEvent(ConfigChangeEvent event) {
        ConfigChangeEnum configChangeEnum = ConfigChangeEnum.fromInt(event.getType());
        logger.debug("接收到事件："+configChangeEnum.getName());
        switch (configChangeEnum){
            case CONFIG_ADD:{this.config((ConfigInfo)event.getSource(),configChangeEnum);break;}
            case CONFIG_EDIT:{this.config((ConfigInfo)event.getSource(),configChangeEnum);break;}
            case CONFIG_DELETE:{this.config((ConfigInfo)event.getSource(),configChangeEnum);break;}
            case FILE_ADD:{this.file((FileInfo)event.getSource(),configChangeEnum);break;}
            case FILE_EDIT:{this.file((FileInfo)event.getSource(),configChangeEnum);break;}
            case FILE_DELETE:{this.file((FileInfo)event.getSource(),configChangeEnum);break;}
            case PROJECT_ADD:{this.project((ProjectInfo)event.getSource(),configChangeEnum);break;}
            case PROJECT_EDIT:{this.project((ProjectInfo)event.getSource(),configChangeEnum);break;}
            case PROJECT_DELETE:{this.project((ProjectInfo)event.getSource(),configChangeEnum);break;}
        }
    }

    /**
     * @description: 项目变更事件
     * @param: source
     * @param: configChangeEnum
     * @return: void
     * @author raorao
     * @date: 2021/11/30 15:36
     */
    private void project(ProjectInfo projectInfo, ConfigChangeEnum configChangeEnum) {
        StringBuilder path=new StringBuilder();
        path.append(ConfigConstant.ZK_SERVICE_PATH).append(ConfigConstant.PATH_DELIMITER);
        path.append(projectInfo.getCode()).append(ConfigConstant.PATH_DELIMITER);
        path.append(projectInfo.getEnvironment()).append(ConfigConstant.PATH_DELIMITER);
        path.append(projectInfo.getVersion()).append(ConfigConstant.PATH_DELIMITER);
        path.append(ConfigConstant.PATH_INFO_PATH).append(ConfigConstant.PATH_DELIMITER);
        if(configChangeEnum.equals(ConfigChangeEnum.PROJECT_DELETE)){
            serviceRegister.delete(path.toString());
        }
    }

    /**
     * @description: 文件变更事件
     * @param: source
     * @param: configChangeEnum
     * @return: void
     * @author raorao
     * @date: 2021/11/30 15:36
     */
    private void file(FileInfo fileInfo, ConfigChangeEnum configChangeEnum) {
        ProjectInfo projectInfo = projectInfoRepository.getById(fileInfo.getProjectId());
        StringBuilder path=new StringBuilder();
        path.append(ConfigConstant.ZK_SERVICE_PATH).append(ConfigConstant.PATH_DELIMITER);
        path.append(projectInfo.getCode()).append(ConfigConstant.PATH_DELIMITER);
        path.append(projectInfo.getEnvironment()).append(ConfigConstant.PATH_DELIMITER);
        path.append(projectInfo.getVersion()).append(ConfigConstant.PATH_DELIMITER);
        path.append(ConfigConstant.PATH_INFO_PATH).append(ConfigConstant.PATH_DELIMITER);
        path.append(fileInfo.getName());
        if(configChangeEnum.equals(ConfigChangeEnum.FILE_DELETE)){
            serviceRegister.delete(path.toString());
        }
    }

    /**
     * @description: 配置变更事件
     * @param: source
     * @param: configChangeEnum
     * @return: void
     * @author raorao
     * @date: 2021/11/30 15:36
     */
    private void config(ConfigInfo configInfo, ConfigChangeEnum configChangeEnum) {
        FileInfo fileInfo = fileInfoRepository.queryById(configInfo.getFileId());
        ProjectInfo projectInfo = projectInfoRepository.getById(fileInfo.getProjectId());
        StringBuilder path=new StringBuilder();
        path.append(ConfigConstant.ZK_SERVICE_PATH).append(ConfigConstant.PATH_DELIMITER);
        path.append(projectInfo.getCode()).append(ConfigConstant.PATH_DELIMITER);
        path.append(projectInfo.getEnvironment()).append(ConfigConstant.PATH_DELIMITER);
        path.append(projectInfo.getVersion()).append(ConfigConstant.PATH_DELIMITER);
        path.append(ConfigConstant.PATH_INFO_PATH).append(ConfigConstant.PATH_DELIMITER);
        path.append(fileInfo.getName()).append(ConfigConstant.PATH_DELIMITER);
        path.append(configInfo.getName());
        if(configChangeEnum.equals(ConfigChangeEnum.CONFIG_DELETE)){
            serviceRegister.delete(path.toString());
        }else {
            //创建配置模型
            ConfigModel configModel=new ConfigModel();
            configModel.setName(configInfo.getName());
            configModel.setVal(configInfo.getVal());
            configModel.setType(configInfo.getType());
            String val= JSON.toJSONString(configModel);
            serviceRegister.save(path.toString(), val);
        }
    }
}
